/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package gerenciadorprojetos.services;

import gerenciadorprojetos.dao.LogRedirecimento;
import gerenciadorprojetos.dao.LogReplanejamento;
import gerenciadorprojetos.dao.NotasProjeto;
import gerenciadorprojetos.dao.hibernate.RedirecionamentoDAO;
import gerenciadorprojetos.dao.hibernate.ProjetoDAO;
import gerenciadorprojetos.dao.hibernate.NotasProjetoDAO;
import gerenciadorprojetos.dao.Projeto;
import gerenciadorprojetos.dao.hibernate.StatusTarefaDAO;
import gerenciadorprojetos.dao.StatusTarefa;
import gerenciadorprojetos.dao.Usuario;
import gerenciadorprojetos.dao.hibernate.ReplanejamentoDAO;
import gerenciadorprojetos.dao.hibernate.UsuarioDAO;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import org.apache.log4j.Logger;

/**
 *
 * @author eduardo
 */
public class ProjetoService {
    private UsuarioService usuarioService;
    private ProjetoDAO projetoDAO;
    private UsuarioDAO usuarioDAO;
    private StatusTarefaDAO statusDAO;
    private RedirecionamentoDAO redirecionamentoDAO;
    private ReplanejamentoDAO replanejamentoDAO;
    private NotasProjetoDAO notasProjetoDAO;
    private Logger logger = Logger.getLogger(UsuarioService.class);

    public ProjetoDAO getProjetoDAO() {
        return projetoDAO;
    }

    public void setProjetoDAO(ProjetoDAO projetoDAO) {
        this.projetoDAO = projetoDAO;
    }

    public UsuarioService getUsuarioService() {
        return usuarioService;
    }

    public void setUsuarioService(UsuarioService usuarioService) {
        this.usuarioService = usuarioService;
    }
    
    public UsuarioDAO getUsuarioDAO() {
        return usuarioDAO;
    }

    public void setUsuarioDAO(UsuarioDAO usuarioDAO) {
        this.usuarioDAO = usuarioDAO;
    }
    
    public StatusTarefaDAO getStatusDAO() {
        return statusDAO;
    }

    public void setStatusDAO(StatusTarefaDAO statusDAO) {
        this.statusDAO = statusDAO;
    }
    
    public boolean cadastrarProjeto(String titulo, String descricao, String executor) {
        try {
            if ( titulo == null || titulo.length() == 0 || descricao == null || descricao.length() == 0) {
                logger.debug("O campos titulo e descricao tem de ser informado !");
                return false;
            }
            
            if ("".equals(executor) || executor == null) {
                logger.debug("O executor tem de ser informado !");
                return false;
            }
            
            Projeto p = new Projeto();
            p.setIdProjeto(projetoDAO.obterMaxID()+1);
            p.setDescricaoProjeto(descricao.toUpperCase());
            p.setDtaCriacaoProjeto(new Date());
            p.setNomeProjeto(titulo.toUpperCase());
            p.setUsuarioByCriador(usuarioService.getUsuarioLogado());
            int id = Integer.parseInt(executor.substring(0, executor.indexOf(" - ")).trim());
            p.setUsuarioByExecutor(usuarioDAO.obtemUsuarioPorId(id));
            p.setStatusTarefa(statusDAO.obterStatusPorDescricao("NOVO"));
            
            if (projetoDAO.adicionarProjeto(p)) {
                logger.debug("Projeto cadastrado com sucesso !");
                return true;
            } else {
                logger.error("Erro ao cadastrar um projeto !");
                logger.error("Funcao de cadastro retornou false !");
                return false;
            }
        } catch (Exception e) {
            logger.error("Erro ao cadastrar um projeto !");
            logger.error("Message: "+e.getMessage());
            return false;
        }
        
    }
    
    public List<String> getProjetos(String status, String executor) {
        StatusTarefa s = null;
        if (status != null) {
            s = statusDAO.obterStatusPorDescricao(status);
            logger.debug("*** Buscando status ***");
        } else {
            logger.debug("*** Status Nulo ***");
        }
        
        Usuario u;
        try {
            u = usuarioDAO.obtemUsuarioPorId(Integer.parseInt(executor.substring(0, executor.indexOf(" - ")).trim()));
        } catch (Exception e) {
            logger.error("Ocorreu um erro ao obter o usuario em getProjetos !");
            logger.error("Mensagem: "+e.getMessage());
            return null;
        }
        
        List<Projeto> p = projetoDAO.obterProjetosPorExecutor(u);
        ListIterator<Projeto> it = p.listIterator();
        
        List<String> saida = new LinkedList<String>();
        Projeto proj;
        
        while (it.hasNext()) {
            proj = it.next();
            
            logger.debug("*** CARREGANDO PROJETO - ID: "+proj.getIdProjeto()+"***");
            if (status == null || s.getDescStatusTarefa().equals(proj.getStatusTarefa().getDescStatusTarefa())) {
                saida.add(new StringBuilder().append(proj.getIdProjeto()+" - "+proj.getNomeProjeto()+" - "+proj.getStatusTarefa().getDescStatusTarefa()).toString());
            } else {
                logger.debug("*** DESPREZANDO O PROJETO - ID:"+proj.getIdProjeto()+" ***");
            }
            
        }
        
        logger.debug("*** RETORNANDO LISTA COM "+saida.size()+" ***");
        return saida;
    }
    
    public String getProjeto(String projeto) {
        logger.debug("getProjeto - entrada: "+projeto);
        int id = Integer.parseInt(projeto.substring(0,projeto.indexOf(" - ")));
        logger.debug("getProjeto - obtendo o projeto com o id "+id);
        Projeto p = this.getProjetoDAO().obtemProjeto(id);
        StringBuilder b = new StringBuilder();
        b.append(p.getIdProjeto());
        b.append(";");
        b.append(p.getNomeProjeto());
        b.append(";");
        b.append(p.getDescricaoProjeto());
        b.append(";");
        
        SimpleDateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm");
        
        if (p.getDtaInicial() != null) {
            b.append(df.format(p.getDtaInicial()));
        } else {
            b.append(" ");
        }
        b.append(";");
        
        if (p.getDtaInicialPlanej() != null) {
            b.append(df.format(p.getDtaInicialPlanej()));
        } else {
            b.append(" ");
        }
        b.append(";");
        
        if (p.getDtaFinal() != null) {
            b.append(df.format(p.getDtaFinal()));
        } else {
            b.append(" ");
        }
        b.append(";");
        
        if (p.getDtaFinalPlanej() != null) {
            b.append(df.format(p.getDtaFinalPlanej()));
        } else {
            b.append(" ");
        }
        b.append(";");
        
        if (p.getUsuarioByExecutor() != null) {
            b.append(p.getUsuarioByExecutor().getIdUsuario()+" - "+p.getUsuarioByExecutor().getNomeUsuario());
        } else {
            b.append(" ");
        }
        b.append(";");
        
        b.append(p.getUsuarioByCriador().getIdUsuario()+" - "+p.getUsuarioByCriador().getNomeUsuario());
        b.append(";");
        
        b.append(p.getStatusTarefa().getDescStatusTarefa());
        
        return b.toString();
    }
    
    public boolean atualizarProjeto(String id, String nome, String desc, String dtaPrevInicio, String dtaPrevTermino, String dtaInicio, String dtaTermino, String executor, String status) {
        
        logger.debug("*** Iniciando atualização !");
        logger.debug("ID: "+id);
        Projeto p = projetoDAO.obtemProjeto(Integer.parseInt(id));
        
        logger.debug("NOME: "+nome);
        p.setNomeProjeto(nome);
        logger.debug("DESC: "+desc);
        p.setDescricaoProjeto(desc);
        
        SimpleDateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm");
        try {
            logger.debug("DTA INI: "+dtaInicio);
            if (dtaInicio != null && (! " ".equals(dtaInicio))) p.setDtaInicial(df.parse(dtaInicio));
            logger.debug("DTA TERM: "+dtaTermino);
            if (dtaTermino != null && (! " ".equals(dtaTermino)))p.setDtaFinal(df.parse(dtaTermino));
            logger.debug("DTA PREV INI: "+dtaPrevInicio);
            if (dtaPrevInicio != null && (! " ".equals(dtaPrevInicio))) p.setDtaInicialPlanej(df.parse(dtaPrevInicio));
            logger.debug("DTA PREV TERM: "+dtaPrevTermino);
            if (dtaPrevTermino != null && (! " ".equals(dtaPrevTermino))) p.setDtaFinalPlanej(df.parse(dtaPrevTermino));
        } catch (ParseException ex) {
            logger.fatal("atualizarProjeto - Convertendo Datas: "+ex.getMessage());
            return false;
        }
        
        logger.debug("EXECUTOR: "+executor);
        Usuario u = usuarioDAO.obtemUsuarioPorId(Integer.parseInt(executor.substring(0,executor.indexOf("-")).trim()));
        
        if (p.getUsuarioByExecutor().getIdUsuario() != u.getIdUsuario()) {
            logger.debug("*** REDIRECIONANDO");
            //redirecionamento
            p.setUsuarioByExecutor(u);
        }
        
        logger.debug("STATUS: "+status);
        p.setStatusTarefa(statusDAO.obterStatusPorDescricao(status));
        
        
        if (projetoDAO.atualizarProjeto(p)) {
            logger.debug("*** PROJETO ATUALIZADO COM SUCESSO !");
            return true;
        } else {
            logger.debug("*** OCORREU UM ERRO AO ATUALIZAR O PROJETO !");
            return false;
        }
    }
    
    public boolean redirecionarProjeto(String id, String executor) {
        logger.debug("*** Iniciando redirecionamento !");
        logger.debug("ID: "+id);
        Projeto p = projetoDAO.obtemProjeto(Integer.parseInt(id));
        
        logger.debug("STATUS ATUAL: "+executor);
        StatusTarefa s = statusDAO.obterStatusPorDescricao("REDIRECIONADO");
        logger.debug("NOVO STATUS: "+s.getDescStatusTarefa());
        p.setStatusTarefa(s);
        
        logger.debug("EXECUTOR: "+executor);
        Usuario uN = usuarioDAO.obtemUsuarioPorId(Integer.parseInt(executor.substring(0,executor.indexOf("-")).trim()));
        
        logger.debug("EXECUTOR ATUAL: "+p.getUsuarioByExecutor().getNomeUsuario());
        Usuario uA = p.getUsuarioByExecutor();
        
        p.setUsuarioByExecutor(uN);
        
        logger.debug("*** Criando redirecionamento !");
        LogRedirecimento l = new LogRedirecimento(getRedirecionamentoDAO().obterMaxID()+1, uA, uN, new Date());
        l.setProjeto(p);
        if (getRedirecionamentoDAO().addRedirecionamento(l)) {
            logger.debug("*** Atualizando o projeto !");
            if (! projetoDAO.atualizarProjeto(p)) {
                logger.debug("*** Erro ao atualizar o projeto !");
                return false;
            }
        } else {
            logger.debug("*** Erro ao criar o log de redirecionamento !");
            return false;
        }
        
        return true;
    }
    
    public boolean replanejaProjeto(String id, String dtaIniPlanej, String dtaFimPlanej) {
        logger.debug("*** Iniciando replanejamento !");
        logger.debug("ID: "+id);
        Projeto p = projetoDAO.obtemProjeto(Integer.parseInt(id));
        LogReplanejamento l = new LogReplanejamento();
        l.setIdProjeto(p.getIdProjeto());
        l.setIdReplanejamento(replanejamentoDAO.obterMaxID()+1);
        l.setDtaReplanejamento(new Date());
        l.setUsuarioResponsavelPlanejamento(usuarioService.getUsuarioLogado());
        l.setAntigaDataInicial(p.getDtaInicialPlanej());
        l.setAntigaDataFinal(p.getDtaFinalPlanej());
        
        SimpleDateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm");
        try {
            logger.debug("DTA INI: "+dtaIniPlanej);
            if (dtaIniPlanej != null && (! " ".equals(dtaIniPlanej))) {
                logger.debug("Atualizando a data inicial do planejamento");
                p.setDtaInicial(df.parse(dtaIniPlanej));
                l.setNovaDataInicial(df.parse(dtaIniPlanej));
            }
            logger.debug("DTA TERM: "+dtaFimPlanej);
            if (dtaFimPlanej != null && (! " ".equals(dtaFimPlanej))) {
                logger.debug("Atualizando a data final do planejamento");
                p.setDtaFinalPlanej(df.parse(dtaFimPlanej));
                l.setNovaDataFinal(df.parse(dtaFimPlanej));
            }
        } catch (ParseException ex) {
            logger.fatal("atualizarProjeto - Convertendo Datas: "+ex.getMessage());
            return false;
        }
        
        if (! replanejamentoDAO.addReplanejamento(l)) {
            logger.debug("Ocorreu um erro ao adicionar o redirecionamento !");
            return false;
        }
        
        if (! projetoDAO.atualizarProjeto(p)) {
            logger.debug("Ocorreu um erro ao atualizar o projeto !");
            return false;
        }
        
        return true;
    }

    public boolean criarNotaProjeto(String idProjeto, String mensagem) {
        logger.debug("Entrando no metodo criarNotaProjeto !");

        if (mensagem == null || mensagem.trim().length() == 0) {
            logger.error("Mensagem da nota é invalida !");
            return false;
        }
        
        logger.debug("Buscando Projeto pelo ID!");

        Projeto proj;
        try {
            String idAux = idProjeto.substring(0,idProjeto.indexOf(" - "));
            int id = Integer.parseInt(idAux);
            proj = projetoDAO.obtemProjeto(id);
        } catch (NumberFormatException exc) {
            logger.error("Erro ao converter o idProjeto para int !",exc);
            return false;
        }
        
        logger.debug("Buscando Criador pelo Usuario Logado!");
        Usuario user = usuarioService.getUsuarioLogado();

        logger.debug("Validando descricao da mensagem!");

        logger.debug("Criando nota!");
        NotasProjeto p = new NotasProjeto();
        p.setIdNotaProjeto(0);
        p.setCriador(user);
        p.setDtaCriacaoNota(new Date());
        p.setMensagem(mensagem);
        p.setProjeto(proj);

        notasProjetoDAO.adicionaNotaProjeto(p);

        return true;
    }

    public RedirecionamentoDAO getRedirecionamentoDAO() {
        return redirecionamentoDAO;
    }

    public void setRedirecionamentoDAO(RedirecionamentoDAO redirecionamentoDAO) {
        this.redirecionamentoDAO = redirecionamentoDAO;
    }

    public ReplanejamentoDAO getReplanejamentoDAO() {
        return replanejamentoDAO;
    }

    public void setReplanejamentoDAO(ReplanejamentoDAO replanejamentoDAO) {
        this.replanejamentoDAO = replanejamentoDAO;
    }

    /**
     * @return the notasProjetoDAO
     */
    public NotasProjetoDAO getNotasProjetoDAO() {
        return notasProjetoDAO;
    }

    /**
     * @param notasProjetoDAO the notasProjetoDAO to set
     */
    public void setNotasProjetoDAO(NotasProjetoDAO notasProjetoDAO) {
        this.notasProjetoDAO = notasProjetoDAO;
    }
    
}
